package com.vortex.cloud.zhsw.xinyang.dto.coordinate;

import com.google.common.collect.Lists;
import com.vortex.cloud.lbs.enums.CoordtypeEnum;
import com.vortex.cloud.lbs.enums.ShapeTypeEnum;
import com.vortex.cloud.lbs.util.MapCoordinateConvertUtils;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Objects;

/**
 * 基础坐标系
 *
 * @author bd
 * @date 2021/6/16 13:49
 */
@Data
public class LngLatBaseDTO {
    private String shapeType;
    private String cordType;
    private String lngLats;

    public LngLatAllDTO transferToLngLatAll() {
        Assert.hasText(this.shapeType, "形状不能为空");
        ShapeTypeEnum shapeTypeEnum = ShapeTypeEnum.getByKey(this.shapeType);
        Assert.notNull(shapeTypeEnum, "不支持" + this.shapeType + "这种形状");
        Assert.hasText(this.cordType, "经纬度类型不能为空");
        CoordtypeEnum coordTypeEnum = CoordtypeEnum.getByKey(this.cordType);
        Assert.notNull(coordTypeEnum, "不支持" + this.cordType + "这种经纬度类型");
        Assert.hasText(this.lngLats, "经纬度不能为空");
        String[] lngLatStrs = this.lngLats.split(";");
        switch (shapeTypeEnum) {
            case POINT:
                Assert.isTrue(lngLatStrs.length == 1, "点只能一组经纬度");
                break;
            case LINE:
                Assert.isTrue(lngLatStrs.length >= 2, "多折线至少两组经纬度");
                break;
            case POLYGON:
                Assert.isTrue(lngLatStrs.length >= 3, "多边形至少三组经纬度");
                break;
            case RECTANGLE:
                Assert.isTrue(lngLatStrs.length == 4, "矩形只能四个组经纬度");
                break;
            case CIRCLE:
                Assert.isTrue(lngLatStrs.length == 1, "圆形只能为经度,纬度,半径的格式");
                break;
            default:
                break;
        }
        List<String> wgs84List = Lists.newArrayList();
        List<String> gcj02List = Lists.newArrayList();
        List<String> bd09List = Lists.newArrayList();
        if (Objects.equals(ShapeTypeEnum.CIRCLE, shapeTypeEnum)) {
            generateCircleShape(coordTypeEnum, lngLatStrs[0], wgs84List, gcj02List, bd09List);
        } else {
            generateOtherShapeType(coordTypeEnum, lngLatStrs, wgs84List, gcj02List, bd09List);
        }

        LngLatAllDTO dto = new LngLatAllDTO();
        dto.setShapeType(this.shapeType);
        dto.setWgs84(StringUtils.join(wgs84List, ";"));
        dto.setBd09(StringUtils.join(bd09List, ";"));
        dto.setGcj02(StringUtils.join(gcj02List, ";"));
        return dto;
    }

    private void generateOtherShapeType(CoordtypeEnum coordTypeEnum, String[] lngLatStrs, List<String> wgs84List, List<String> gcj02List, List<String> bd09List) {
        double radius;
        String[] lngLatArr;
        lngLatArr = lngLatStrs;
        int len = lngLatStrs.length;
        for (int i = 0; i < len; ++i) {
            String lngLatStr = lngLatArr[i];
            String[] lngLats = lngLatStr.split(",");
            Assert.isTrue(lngLats.length == 2, "经纬度只能为经度,纬度的格式");
            radius = NumberUtils.toDouble(lngLats[0]);
            double lat = NumberUtils.toDouble(lngLats[1]);
            double[] bd09 = null;
            double[] wgs84 = null;
            double[] gcj02 = null;
            switch (coordTypeEnum) {
                case gps:
                    wgs84 = new double[]{radius, lat};
                    gcj02 = MapCoordinateConvertUtils.wgs84Togcj02(radius, lat);
                    bd09 = MapCoordinateConvertUtils.wgs84Tobd09(radius, lat);
                    break;
                case baidu:
                    wgs84 = MapCoordinateConvertUtils.bd09Towgs84(radius, lat);
                    bd09 = new double[]{radius, lat};
                    gcj02 = MapCoordinateConvertUtils.bd09Togcj02(radius, lat);
                    break;
                case gaode:
                    wgs84 = MapCoordinateConvertUtils.gcj02Towgs84(radius, lat);
                    bd09 = MapCoordinateConvertUtils.gcj02Tobd09(radius, lat);
                    gcj02 = new double[]{radius, lat};
                    break;
                default:
                    break;
            }

            if (wgs84 != null) {
                wgs84List.add(StringUtils.join(ArrayUtils.toObject(wgs84), ","));
            }

            if (gcj02 != null) {
                gcj02List.add(StringUtils.join(ArrayUtils.toObject(gcj02), ","));
            }

            if (bd09 != null) {
                bd09List.add(StringUtils.join(ArrayUtils.toObject(bd09), ","));
            }
        }
    }

    private void generateCircleShape(CoordtypeEnum coordTypeEnum, String lngLatStr, List<String> wgs84List, List<String> gcj02List, List<String> bd09List) {
        String[] lngLatArr;
        lngLatArr = lngLatStr.split(",");
        double radius;
        double[] bd09;
        Assert.isTrue(lngLatArr.length == 3, "圆形只能为经度,纬度,半径的格式");
        double lng = NumberUtils.toDouble(lngLatArr[0]);
        double lat = NumberUtils.toDouble(lngLatArr[1]);
        radius = NumberUtils.toDouble(lngLatArr[2]);
        double[] wgs84 = null;
        double[] gcj02 = null;
        bd09 = null;
        switch (coordTypeEnum) {
            case gps:
                wgs84 = new double[]{lng, lat};
                gcj02 = MapCoordinateConvertUtils.wgs84Togcj02(lng, lat);
                bd09 = MapCoordinateConvertUtils.wgs84Tobd09(lng, lat);
                break;
            case baidu:
                wgs84 = MapCoordinateConvertUtils.bd09Towgs84(lng, lat);
                bd09 = new double[]{lng, lat};
                gcj02 = MapCoordinateConvertUtils.bd09Togcj02(lng, lat);
                break;
            case gaode:
                wgs84 = MapCoordinateConvertUtils.gcj02Towgs84(lng, lat);
                bd09 = MapCoordinateConvertUtils.gcj02Tobd09(lng, lat);
                gcj02 = new double[]{lng, lat};
                break;
            case mapbar:
            case Beijing54:
            case Xian80:
            case suzhou:
            case nantong94:
            default:
                break;
        }

        if (wgs84 != null) {
            wgs84List.add(StringUtils.join(ArrayUtils.toObject(wgs84), ",") + "," + radius);
        }

        if (gcj02 != null) {
            gcj02List.add(StringUtils.join(ArrayUtils.toObject(gcj02), ",") + "," + radius);
        }

        if (bd09 != null) {
            bd09List.add(StringUtils.join(ArrayUtils.toObject(bd09), ",") + "," + radius);
        }
    }
}
